﻿using HalconDotNet;
using Halcon二次开发.Controller.CamerForm交互;
using Halcon二次开发.Controller.主界面交互;
using Halcon二次开发.Controller.卡尺;
using Halcon二次开发.Model;
using Halcon二次开发.Model.储存每个Controller的单例对象;
using Halcon二次开发.Model.储放所有单例.储存每个单例界面;
using Halcon二次开发.Model.自定义控件;
using Halcon二次开发.Tools;
using Halcon二次开发.View.相机;
using Halcon二次开发.View.输入框;
using Halcon二次开发.View.九点标定;
using Halcon二次开发.View.卡尺;
using Halcon二次开发.View.定位跟随;
using Halcon二次开发.View.找圆_线_矩形;
using Halcon二次开发.View.文本显示工具;
using Halcon二次开发.View.模板匹配;
using Halcon二次开发.View.膨胀与腐蚀;
using Halcon二次开发.View.距离转换工具;
using log4net;
using log4net.Config;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Halcon二次开发.Controller.数据加载与保存;
using System.Reflection;
using Halcon二次开发.View.多模板匹配;
using Halcon二次开发.View.Socket通信;
[assembly: XmlConfigurator(ConfigFile ="..\\..\\Data\\日志配置文件\\log4net.config",Watch =true)]
namespace Halcon二次开发
{
    public partial class Form1 : Form
    {
        /// <summary>
        /// 工程文件路径
        /// </summary>
        public string filePath = $@"..\..\Data\工程文件\";
        //日志文件对象
        private static readonly ILog log=LogManager.GetLogger(typeof(Form1));
        public Form1()
        {
            InitializeComponent();
            //单例窗体
            FormDb.Db.Add("Form1", this);
        }

        /// <summary>
        /// 隐藏窗口
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void 隐藏窗口ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            splitContainer1.SplitterDistance = 0;
        }

        private void 固定ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            splitContainer1.SplitterDistance = splitContainer1.Width/2-20;
        }

        private void toolStripMenuItem1_Click(object sender, EventArgs e)
        {
            splitContainer1.SplitterDistance = 200;
        }

        private void 显示工具箱ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            splitContainer1.SplitterDistance = 200;
        }

        private void 适应图像ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //hSmartWindowControl1.HalconWindow.
        }

        /// <summary>
        /// 双击添加流程节点
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void treeView1_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            int index = tabControl2.SelectedIndex;
            if (index == -1) {
                textBox1.AppendText("请先添加工程文件!\r\n");
                return;
            }
            HwindowFlowNodeUrseControl s = tabControl2.TabPages[index].Tag as HwindowFlowNodeUrseControl;
            //这里要判断一下
            foreach (var item in StaicResouce.formCollections) 
            {
                if (item.name == tabControl2.TabPages[index].Text)
                {
                    item.Btn_Double_Click(s,treeView1);
                }
            }
        }

        /// <summary>
        /// 新建工程
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void 新建工程ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            NameForm nameForm = new NameForm();
            nameForm.ShowDialog(this);
            if (nameForm.name=="")
            {
                return;
            }
            StaicResouce.FilesName.Add(nameForm.name);
            //新增菜单
            AddMenu(nameForm.name);
            //对这个动作进行新增
            Form1Controller form1Controller = new Form1Controller();
            form1Controller.name = nameForm.name;
            StaicResouce.formCollections.Add(form1Controller);
            //添加界面
            HwindowFlowNodeUrseControl hwindowFlowNodeUrseControl = new HwindowFlowNodeUrseControl();
            
            //这俩步非常重要,动作绑定窗体
            hwindowFlowNodeUrseControl.name = nameForm.name;
            hwindowFlowNodeUrseControl.form1Controller = form1Controller;
            //这条需要赋值一下,因为第一次Page页选择事件不会被触发
            StaicResouce.HwindowFlowNodeUrse = hwindowFlowNodeUrseControl;
            Utiy.AddPage(hwindowFlowNodeUrseControl, tabControl2, nameForm.name);
            //对这个新增的页面进行记录
            StaicResouce.HomeForms.Add(hwindowFlowNodeUrseControl);
        }

        /// <summary>
        /// Tab页更改时发生
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tabControl2_SelectedIndexChanged(object sender, EventArgs e)
        {
            int index = tabControl2.SelectedIndex;
            if (index == -1) return;
            HwindowFlowNodeUrseControl s = tabControl2.TabPages[index].Tag as HwindowFlowNodeUrseControl;
            StaicResouce.HwindowFlowNodeUrse = s;
        }
        //Text消息框更改,写入日志文件
        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            log.Error(textBox1.Text);
        }
        /// <summary>
        /// 预加载数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_Load(object sender, EventArgs e)
        {
            //加载我们的Socket通信界面
            SocketForm.GetSocketForm();

            string state = filePath;//根目录 //例子 ：\Data\工程文件    
            string[] stateS = Directory.GetDirectories(state);// 查询所有工程文件
            foreach (string item in stateS)//循环创建所有工程文件
            {
                //将工程名提取出来
                string[] stateName = item.Split(new char[] { '工', '程', '文', '件', '\\' }, StringSplitOptions.RemoveEmptyEntries);
                string name = stateName[stateName.Length - 1];

                StaicResouce.FilesName.Add(name);
                //对这个动作进行新增
                Form1Controller form1Controller = new Form1Controller();
                form1Controller.name = name;
                StaicResouce.formCollections.Add(form1Controller);
                //添加界面
                HwindowFlowNodeUrseControl hwindowFlowNodeUrseControl = new HwindowFlowNodeUrseControl();
                //这俩步非常重要,动作绑定窗体
                hwindowFlowNodeUrseControl.name = name;
                hwindowFlowNodeUrseControl.form1Controller = form1Controller;
                //这条需要赋值一下,因为第一次Page页选择事件不会被触发
                StaicResouce.HwindowFlowNodeUrse = hwindowFlowNodeUrseControl;
                Utiy.AddPage(hwindowFlowNodeUrseControl, tabControl2, name);

                //对这个新增的页面进行记录
                StaicResouce.HomeForms.Add(hwindowFlowNodeUrseControl);

                //遍历流程文件 创建项目流程
                string flowFile = item + "\\流程\\流程.txt";
                if (File.Exists(flowFile))
                {
                    string[] tools = File.ReadAllLines(flowFile);
                    for (int i = 0; i < tools.Length; i++)
                    {

                        string[] results = tools[i].Split(new char[] { ',', ':' }, StringSplitOptions.RemoveEmptyEntries);
                        object classInstance = CreateObjectByName(results[0]);
                        //这里就是2个PMA模板匹配所需的构造方法
                        if (classInstance is H_PMAAlignToolForm)
                        {
                            (classInstance as H_PMAAlignToolForm).SetPathNodes(filePath + hwindowFlowNodeUrseControl.name + "工程文件", results[2].Trim());
                        }
                        else if (classInstance is H_PMA_S_AlignToolForm)
                        {
                            (classInstance as H_PMA_S_AlignToolForm).SetPathNodes(filePath + hwindowFlowNodeUrseControl.name + "工程文件", results[2].Trim());
                        }

                        if ((classInstance is Form))
                        {
                            //获取到每个类中的SetJsonPaths方法
                            MethodInfo methodInfo = classInstance.GetType().GetMethod("SetJsonPaths");
                            if (methodInfo != null)
                            {
                                object[] objs = new object[2] { filePath + hwindowFlowNodeUrseControl.name + "工程文件", results[2].Trim() };
                                methodInfo.Invoke(classInstance, objs);
                            }
                            form1Controller.AddHeadNode((classInstance as Form), results[2].Trim(), hwindowFlowNodeUrseControl, int.Parse(results[3]));
                            foreach (TreeNode targetNode in hwindowFlowNodeUrseControl.treeView1.Nodes)
                            {
                                if (targetNode.Name == results[2].Trim())
                                {
                                    //更改子节点的连接状态 
                                    AddChildLink(ref i, tools, targetNode);
                                }
                            }
                        }
                    }
                }

                //自动运行一次
                hwindowFlowNodeUrseControl.toolStripButton1_Click(null, null);
                AddMenu(name);
            }
            

            if (stateS.Length > 0)
            {
                tabControl2.SelectedIndex = 0;
            }
        }

        private void AddMenu(string name)
        {
            ToolStripMenuItem menuItem1 = new ToolStripMenuItem(name + "工程文件");
            menuItem1.Name = name + "工程文件";
            工程管理ToolStripMenuItem.DropDownItems.Add(menuItem1);
            menuItem1.Tag = 工程管理ToolStripMenuItem;

            ToolStripMenuItem menuItemMove = new ToolStripMenuItem("移除");
            menuItem1.DropDownItems.Add(menuItemMove);
            menuItemMove.Tag = menuItem1;
            menuItemMove.Click += MenuItemMove_Click;

            ToolStripMenuItem menuItemdelete = new ToolStripMenuItem("删除");
            menuItem1.DropDownItems.Add(menuItemdelete);
            menuItemdelete.Tag = menuItem1;
            menuItemdelete.Click += MenuItemDelete_Click;
        }

        /// <summary>
        /// 移除工程文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MenuItemDelete_Click(object sender, EventArgs e)
        {
            RemoveParent(sender,"delete");
            
        }
        /// <summary>
        /// 删除工程文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MenuItemMove_Click(object sender, EventArgs e)
        {

            RemoveParent(sender,"move");
        }
        /// <summary> 
        /// 删除父菜单和流程图和tabpag
        /// </summary>
        /// <param name="sender"></param>
        private  void RemoveParent(object sender,string mode)
        {
            
            //当前节点对象
            ToolStripMenuItem current = sender as ToolStripMenuItem;
            //父节点对象
            ToolStripMenuItem parent = current.Tag as ToolStripMenuItem;
            //删除工程文件
           string[] str= parent.Text.Split(new char[] { '工', '程', '文', '件' }, StringSplitOptions.RemoveEmptyEntries);
            HwindowFlowNodeUrseControl u = null;
            foreach (HwindowFlowNodeUrseControl hd in StaicResouce.HomeForms)
            {
               if (hd.name == str[0].Trim())
                {
                    u = hd;
                }
            }
            if (u != null)
            {
                StaicResouce.HomeForms.Remove(u);
            }
            //删除tabpag
            Utiy.RemovePage(tabControl2, str[0].Trim());
            //彻底删除工程文件
            if (mode == "delete")
            {
                Directory.Delete(filePath+ "\\"+ parent.Text,true);
                //删除记录工程文件名的集合
                StaicResouce.FilesName.Remove(str[0].Trim());
            }
            //根点对象
            ToolStripMenuItem head = parent.Tag as ToolStripMenuItem;
            //删除父菜单
            head.DropDownItems.Remove(parent);
        }

        /// <summary>
        /// 递归读取子节点的连线状态
        /// </summary> 
        public void AddChildLink(ref int i, string[] tools, TreeNode node)
        {
            if (!(i < tools.Length - 1) || !tools[i + 1].Contains("<—")) return;
            string[] strs=tools[i + 1].Split(new char[] { ':' },StringSplitOptions.RemoveEmptyEntries);
            foreach (TreeNode item in node.Nodes)
            {
                if (item.Name == strs[0])
                {
                    item.Text = strs[1];
                    item.ForeColor= Color.Green;
                    break;
                }
            }
            i++;
            AddChildLink(ref i, tools, node);
        }
        private static object CreateObjectByName(string className)
        {
            // 通过类名获取类型信息
            Type type = Type.GetType(className);
            if (type == null)
            {
                return null; // 类型不存在
            }

            // 使用Activator.CreateInstance创建类的实例
            return Activator.CreateInstance(type);
        }
        
        /// <summary>
        /// 自动保存数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            foreach (HwindowFlowNodeUrseControl hd in StaicResouce.HomeForms)
            {

                string state = filePath + hd.name + "工程文件\\";//例子 ：\Data\工程文件\123工程文件    state
                string flowPath = state + "流程\\";              //例子：\Data\工程文件\123工程文件\流程   flowPath
                string flowFilePath = flowPath +"流程.txt";          //例子：\Data\工程文件\123工程文件\流程\流程.txt   flowFilePath
                if (!Directory.Exists(flowPath))//创建流程文件夹 
                {
                    Directory.CreateDirectory(flowPath);
                }
                using (File.Create(flowFilePath)) { }//重新创建工程文件
                //创建或者覆盖界面数据文件夹
                string flowsPaths = state + "界面数据";
                if (!Directory.Exists(flowsPaths))
                {
                    //不存在就创建文件夹
                    Directory.CreateDirectory(flowsPaths);
                }else
                {
                    //存在就删除在创建文件夹
                    Directory.Delete(flowsPaths, true);
                    Directory.CreateDirectory(flowsPaths);
                }

                TreeNodeCollection headNodes= hd.treeView1.Nodes;
                bool delFilePaper = true;
                foreach (TreeNode headNode in headNodes)//新键所有工具根点文件夹
                {
                    //在这里将我们的相机工具进行文件的处理
                    if (headNode.Name.Equals("CamerTool0"))
                    {
                        delFilePaper = false;
                    }
                    string hPath= flowsPaths + "\\"+ headNode.Name;//例子：\Data\工程文件\123工程文件\模板匹配0   hPath
                    if (!Directory.Exists(hPath))
                    {
                        Directory.CreateDirectory(hPath);
                    }
                    using (StreamWriter writer = new StreamWriter(flowFilePath, append: true))
                    {
                        string xxx = headNode.Text;
                        writer.WriteLine(headNode.Tag.ToString()+":"+headNode.ImageIndex);// 窗体对象+根节点名+根节点显示的图片
                        foreach (TreeNode item in headNode.Nodes)//连接状态的子节点对象
                        {
                            if (item.Text.Contains("<—"))
                            {
                                writer.WriteLine(item.Name+":"+item.Text);
                            }
                        }
                    }
                }
                //处理我们的相机工具中的文件了
                if (delFilePaper)
                {
                    //如果有这个工具就可以去删除我们的相机文件了
                    if (Directory.Exists(state + "相机图片数据"))
                    {
                        //有这个文件夹就可以进行覆盖这个文件夹了
                        Directory.Delete(state + "相机图片数据", true);
                        Directory.CreateDirectory(state + "相机图片数据");
                    }
                }
            }
            //存储每个界面的数据
            new StorageDataController(filePath).Storage();
            //调用Socket界面的关闭事件,关闭是将Socket数据进行保存
            new StoreFormHelp().Store(SocketForm.GetSocketForm(), SocketForm.GetSocketForm().jsonPath);
            //存储消息记录
            HelpJsons.Write<string>(SocketForm.GetSocketForm().listSendRecord, SocketForm.GetSocketForm().jsonSendPath);
            HelpJsons.Write<string>(SocketForm.GetSocketForm().listReceiveRecord, SocketForm.GetSocketForm().jsonReceivePath);

        }

        private void socket通信ToolStripMenuItem_Click(object sender, EventArgs e)
        {
           SocketForm.GetSocketForm().Show();
        }

        /// <summary>
        /// 三菱通信
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void 三菱通信ToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }
    }
}
